﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BruteForceSerializer.Tests.TestClasses;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using NUnit.Framework;
using TypeResolve;

namespace BruteForceSerializer.Tests
{
	[TestFixture, Explicit]
	public class test_newJsonDotNet
	{
		[Test]
		public void Tests()
		{
			//TestSerializeDeserializeClass<KlasseMitByteArray>();
			//TestSerializeDeserializeClass<Parent>();
			TestSerializeDeserializeClass<KlasseMitTyp>();
		}

		private static void TestSerializeDeserializeClass<T>() where T : new()
		{
			var serializerSettings = new JsonSerializerSettings {ContractResolver = ConverterContractResolver.Instance};
			var serialized = JsonConvert.SerializeObject(new T(), serializerSettings);
			Console.WriteLine(serialized);
			var deserialized = JsonConvert.DeserializeObject<T>(serialized, serializerSettings);
		}
	}

	public class ConverterContractResolver : DefaultContractResolver
	{
		public static readonly ConverterContractResolver Instance = new ConverterContractResolver();

		protected override JsonContract CreateContract(Type objectType)
		{
			var contract = base.CreateContract(objectType);

			// this will only be called once and then cached
			if (objectType == typeof (Type) || objectType.FullName == "System.RuntimeType")
				contract.Converter = new TypeConverter();

			return contract;
		}
	}

	public class TypeConverter : JsonConverter
	{
		public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
		{
			serializer.Serialize(writer, TypeResolver.TypeToString((Type)value));
		}

		public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
		{
			var typeStr = serializer.Deserialize<string>(reader);
			return TypeResolver.Resolve(typeStr);
		}

		public override bool CanConvert(Type objectType)
		{
			return true; //(objectType == typeof (Type));
		}
	}
}
